package com.whf.android.jar.base.mvp;

import com.blankj.utilcode.util.GsonUtils;
import com.blankj.utilcode.util.JsonUtils;
import com.blankj.utilcode.util.ToastUtils;
import com.whf.android.jar.app.Latte;
import com.whf.android.jar.constants.HttpConstant;
import com.whf.android.jar.net.HttpCode;
import com.whf.android.jar.util.log.LatteLogger;

import java.lang.ref.WeakReference;
import java.lang.reflect.Type;
import java.util.List;

/**
 * @author Administrator
 */
public abstract class BasePresenter<M extends IModel, V extends IView> implements IPresenter<M, V> {
    /**
     * 使用弱引用来防止内存泄漏
     */
    private WeakReference<V> wrf;
    protected M model;
    protected V view;

    @Override
    public void registerModel(M model) {
        this.model = model;
    }

    @Override
    public void registerView(V view) {
        wrf = new WeakReference<V>(view);
    }

    @Override
    public V getView() {
        return wrf == null ? null : wrf.get();
    }

    /**
     * 在Activity或Fragment卸载时调用View结束的方法
     */
    @Override
    public void destroy() {
        if (wrf != null) {
            wrf.clear();
            wrf = null;
        }
        onViewDestroy();
    }

    @Override
    public void onError(int code, String msg) {
        if (getView() != null) {
            getView().hideLoading();
            if (Latte.getSignExpiration() == code) {
                getView().outSignIn();
            } else {
                if (HttpCode.CODE_404 == code) {
                    ToastUtils.showShort("服务器找不到请求的接口");
                } else if (HttpCode.CODE_500 == code && Latte.getServerError()) {
                    ToastUtils.showShort("服务器遇到错误，无法完成请求");
                } else if (HttpCode.CODE_501 == code && Latte.getServerError()) {
                    ToastUtils.showShort("服务器无法识别请求方法");
                } else if (HttpCode.CODE_502 == code && Latte.getServerError()) {
                    ToastUtils.showShort("服务器网关或代理错误，无法完成请求");
                } else if (HttpCode.CODE_503 == code && Latte.getServerError()) {
                    ToastUtils.showShort("服务器目前无法使用");
                } else if (HttpCode.CODE_504 == code && Latte.getServerError()) {
                    ToastUtils.showShort("服务器网关或代理超时，无法完成请求");
                } else if (HttpCode.CODE_505 == code && Latte.getServerError()) {
                    ToastUtils.showShort("服务器不支持请求中所用的 HTTP 协议版本");
                } else {
                    ToastUtils.showShort(msg);
                }
            }
        }
    }

    @Override
    public void onFailure() {
        if (getView() != null) {
            getView().hideLoading();
            ToastUtils.showShort("连接服务器失败，请稍后再试。");
        }
    }

    /**
     * 数据解析
     *
     * @param mJsonData:
     * @param type:
     * @return 解析后的数据
     */
    protected <Te> List<Te> fromJson(String mJsonData, final Type type) {
        try {
            return GsonUtils.fromJson(mJsonData, GsonUtils.getListType(type));
        } catch (Exception e) {
            LatteLogger.e("接口字段类型改了；" + e.getMessage());
            return null;
        }
    }

    /**
     * 数据解析(分页)
     *
     * @param mJsonData:
     * @param type:
     * @return 解析后的数据
     */
    protected <Te> List<Te> fromJsonRecords(String mJsonData, final Type type) {
        try {
            final String records = JsonUtils.getString(mJsonData, HttpConstant.RECORDS);
            return GsonUtils.fromJson(records, GsonUtils.getListType(type));
        } catch (Exception e) {
            LatteLogger.e("接口字段类型改了；" + e.getMessage());
            return null;
        }
    }

    /**
     * 数据解析(不分页)
     *
     * @param type:
     * @return 解析后的数据
     */
    protected <Te> List<Te> fromJsonList(String mJsonData, final Type type) {
        try {
            final String lists = JsonUtils.getString(mJsonData, HttpConstant.LIST);
            return GsonUtils.fromJson(lists, GsonUtils.getListType(type));
        } catch (Exception e) {
            LatteLogger.e("接口字段类型改了；" + e.getMessage());
            return null;
        }
    }

    /**
     * 停止请求等操作
     */
    protected abstract void onViewDestroy();

}
